import { useAirCityStore } from '@/stores/aircity'
import { watch, ref, Ref } from 'vue'
interface Building {
	init: () => Promise<any>
	open: () => Promise<any>
	close: () => Promise<any>
	toggleFloor: (floorNum: number) => Promise<any>
	exit: () => Promise<any>
	hideFloorNum: Ref<number[] | undefined>
	isOnReady: Ref<boolean>
	isClose: Ref<boolean>
	isStopRun: Ref<boolean>
	isPullFloor: Ref<boolean>
}
interface Option {
	layers: string[] //图层数组
	spend: number // 每次抬起速度
	displace: number //每次抬起距离
	totalDistance: number //抬起总距离
	totalfloorDisplace: number //楼层抽拉总位移
	floorSpend: number //楼层每次位移速度
	floorDisplace: number //楼层每次位移距离
	direction: 'east' | 'west' | 'south' | 'north' | number //楼层抽拉方向 Yaw取值 0是正东 逆时针
}
const airCityStore = useAirCityStore()
export const useBuilding = (option: Option): Building => {
	let layersIds: string[] = [] //楼层ID
	let customObjectIds: string[] = [] //自定义对象ID
	let isOnReady = ref<boolean>(false) //模型是否准备完毕
	let floors: any = [] //楼层数组
	let isStopRun = ref<boolean>(true) //是否停止位移
	let isClose = ref<boolean>(true) //是否关闭楼层拆解
	let isPullFloor = ref<boolean>(false) //是否抽出楼层
	let openedFloors: any = [] //已经打开的楼层
	let currentPullFloor: any = null //当前抽出的楼层
	const yawRad: number = ((option.direction as number) * Math.PI) / 180
	const hideFloorIds = ref<string[]>()
	const hideFloorNum = ref<number[]>()
	/**
	 * @description: 通过TileLayer添加自定义对象并隐藏原始图层
	 * @param {this.tileLayers} 图层id及objectId
	 * @return {*}
	 */
	const init = async (): Promise<any> => {
		const { layers } = option
		if (!layers.length || isOnReady.value) return
		layersIds = airCityStore.GetTreeIdByName(layers)
		const { data } = await __g.tileLayer.getObjectIDs(layersIds)
		const ctmObjArr = data.map((item: { id: string; objectIds: string[] }, index: number) => {
			const id = `${item.id}@${index}`
			const tileLayerId = item.id
			const objectId = item.objectIds

			customObjectIds.push(id)
			return {
				id,
				tileLayerId,
				objectId,
				smoothMotion: 0, //1: 平滑插值，0: 跳跃
				coordinateType: 0,
				//location, //保持原有的模型坐标
				//rotation, //保持原有的模型旋转值
				// scale, //保持原有的模型大小
				UserData: JSON.stringify(layers.length - index), //定义用户自定义数据 用来后面点击模型获取到楼层信息
				groupId: `拆楼`,
			}
		})
		await __g.customObject.delete(customObjectIds)
		await __g.customObject.addByTileLayer(ctmObjArr, null)
		await __g.infoTree.hide(layersIds, null)
		const getctmObjResult: any = await __g.customObject.get(customObjectIds)
		floors = getctmObjResult.data
		isOnReady.value = true
		console.log('%c 准备完毕', 'color:green')
	}
	/**
	 * 抬起楼层-开启拆楼
	 */
	const open = async (): Promise<any> => {
		return new Promise((resolve) => {
			// 是否拿到模型信息  只有位移完毕后才可以继续下一步操作 已经处于关闭状态
			if (isOnReady.value && isStopRun.value && isClose.value) {
				// 打开位移状态
				isStopRun.value = false
				let total = 0
				const { spend, displace, totalDistance } = option
				const cloneFloors = JSON.parse(JSON.stringify(floors))
				const openTimer = setInterval(() => {
					__g.customObject.updateBegin()
					cloneFloors.forEach((customObject: any, index: number) => {
						customObject.location[2] = customObject.location[2] + displace * (index + 1)
						__g.customObject.setLocation(customObject.id, customObject.location)
					})
					__g.customObject.updateEnd()
					total += displace
					if (total >= totalDistance) {
						clearInterval(openTimer)
						isClose.value = false
						isStopRun.value = true
						openedFloors = cloneFloors
						resolve('开启楼层完毕！')
					}
				}, spend)
			} else {
				!isOnReady.value
					? console.log('%c 尚未获取到模型信息，请稍后', 'color:red')
					: !isStopRun.value
					? console.log('%c 正处于位移状态，请稍后', 'color:red')
					: !isClose.value
					? console.log('%c 已经是开启状态', 'color:red')
					: 0
			}
		})
	}
	/**
	 * 关闭楼层
	 */
	const close = async (): Promise<any> => {
		//处于开启状态才能执行关闭
		if (!isClose.value && isStopRun.value) {
			//先收回抽出楼层
			if (currentPullFloor) {
				await takeBack(JSON.parse(JSON.stringify(currentPullFloor)))
				currentPullFloor = null
			}
			return new Promise((resolve) => {
				let total = 0
				const { spend, displace, totalDistance } = option
				const openTimer = setInterval(() => {
					__g.customObject.updateBegin()
					openedFloors.forEach((customObject: any, index: number) => {
						customObject.location[2] = customObject.location[2] - displace * (index + 1)
						__g.customObject.setLocation(customObject.id, customObject.location)
					})
					__g.customObject.updateEnd()
					total += displace
					if (total >= totalDistance) {
						clearInterval(openTimer)
						isClose.value = true
						isStopRun.value = true
						openedFloors = null
						resolve('关闭楼层完毕！')
					}
				}, spend)
			})
		} else {
			!isOnReady.value
				? console.log('%c 尚未获取到模型信息，请稍后', 'color:red')
				: !isStopRun.value
				? console.log('%c 正处于位移状态，请稍后', 'color:red')
				: isClose.value
				? console.log('%c 已经是关闭状态', 'color:red')
				: 0
		}
	}
	/**
	 * 退出拆楼
	 */
	const exit = async (): Promise<any> => {
		await __g.customObject.delete(customObjectIds)
		await __g.infoTree.show(layersIds, null)
		reset()
	}
	const reset = async (): Promise<any> => {
		layersIds = [] //楼层ID
		customObjectIds = [] //自定义对象ID
		isOnReady.value = false //模型是否准备完毕
		floors = [] //楼层数组
		isStopRun.value = true //是否停止位移
		isClose.value = true //是否关闭楼层拆解
		isPullFloor.value = false //是否抽出楼层
		openedFloors = [] //已经打开的楼层
		currentPullFloor = null //当前抽出的楼层
		hideFloorIds.value = undefined
		hideFloorNum.value = undefined
	}
	/**
	 *抽拉楼层
	 * @param floorNum 目标楼层数
	 * @returns
	 */
	const toggleFloor = async (floorNum: number): Promise<any> => {
		if (isOnReady.value && isStopRun.value && !isClose.value) {
			// 打开位移状态
			isStopRun.value = false
			let total = 0
			const { floorSpend, floorDisplace, direction, totalfloorDisplace } = option
			const cloneFloors = JSON.parse(JSON.stringify(floors))
			const currentFloor = cloneFloors[floorNum - 1]
			if (currentPullFloor) {
				await takeBack(JSON.parse(JSON.stringify(currentPullFloor)))
				if (currentPullFloor?.id == currentFloor.id) {
					currentPullFloor = null
					isPullFloor.value = false
					return
				}
			}
			isStopRun.value = false
			return new Promise((resolve) => {
				let location0 = 0
				let location1 = 0
				const openTimer = setInterval(() => {
					if (typeof direction == 'number') {
						location0 = floorDisplace * Math.cos(yawRad)
						location1 = floorDisplace * Math.sin(yawRad)
					} else {
						location0 = direction === 'east' ? floorDisplace : direction === 'west' ? -floorDisplace : 0
						location1 = direction === 'north' ? floorDisplace : direction === 'south' ? -floorDisplace : 0
					}

					if (currentPullFloor?.id != currentFloor.id) {
						currentFloor.location[0] += location0
						currentFloor.location[1] += location1
						__g.customObject.setLocation(currentFloor.id, [
							currentFloor.location[0],
							currentFloor.location[1],
							openedFloors[floorNum - 1].location[2],
						])
					}

					total += floorDisplace
					if (total >= totalfloorDisplace) {
						clearInterval(openTimer)
						isClose.value = false
						isStopRun.value = true
						currentPullFloor = currentFloor
						currentPullFloor.location[2] = openedFloors[floorNum - 1].location[2]
						resolve('抽出楼层完毕！')
					}
				}, floorSpend)
			})
		} else {
			!isOnReady.value
				? console.log('%c 尚未获取到模型信息', 'color:red')
				: !isStopRun.value
				? console.log('%c 正处于位移状态，请稍后', 'color:red')
				: isClose.value
				? console.log('%c 先开启楼层分解，请稍后', 'color:red')
				: 0
		}
	}
	/**
	 * 收回抽出的楼层
	 * @param currentPullFloor 当前抽出的楼层
	 */
	const takeBack = async (currentPullFloor: any): Promise<any> => {
		return new Promise((resolve) => {
			const { floorSpend, floorDisplace, direction, totalfloorDisplace } = option
			let total = 0
			let location0 = 0
			let location1 = 0
			if (typeof direction == 'number') {
				location0 = floorDisplace * Math.cos(yawRad)
				location1 = floorDisplace * Math.sin(yawRad)
			} else {
				location0 = direction === 'east' ? floorDisplace : direction === 'west' ? -floorDisplace : 0
				location1 = direction === 'north' ? floorDisplace : direction === 'south' ? -floorDisplace : 0
			}
			// const location0 = direction === 'east' ? floorDisplace : direction === 'west' ? -floorDisplace : 0
			// const location1 = direction === 'north' ? floorDisplace : direction === 'south' ? -floorDisplace : 0
			const openTimer = setInterval(() => {
				currentPullFloor.location[0] -= location0
				currentPullFloor.location[1] -= location1
				__g.customObject.setLocation(currentPullFloor.id, [
					currentPullFloor.location[0],
					currentPullFloor.location[1],
					currentPullFloor.location[2],
				])
				total += floorDisplace
				if (total >= totalfloorDisplace) {
					clearInterval(openTimer)
					isStopRun.value = true
					resolve('收回楼层结束！')
				}
			}, floorSpend)
		})
	}
	/**
	 * 监听需要隐藏的楼层
	 */
	watch(hideFloorNum, () => {
		if (isClose.value) {
			hideFloorIds.value = hideFloorNum.value!.map((num) => customObjectIds[num - 1])
			const needshowFloorIds = customObjectIds.filter((customObjectId) => {
				return hideFloorIds.value!.some((hideFloorId) => hideFloorId != customObjectId)
			})
			__g.customObject.show(needshowFloorIds)
			__g.customObject.hide(hideFloorIds.value)
		} else {
			console.log('%c 先收起关闭楼层拆解', 'color:red')
		}
	})
	return { init, open, close, toggleFloor, hideFloorNum, isOnReady, isClose, isStopRun, isPullFloor, exit }
}
